package com.miniot.base.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miniot.base.dto.BoundDetailDTO;
import com.miniot.base.dto.BoundManageDTO;
import com.miniot.base.entity.*;
import com.miniot.base.mapper.BoundDetailMapper;
import com.miniot.base.mapper.BoundManageMapper;
import com.miniot.base.mapper.WarehouseManageMapper;
import com.miniot.base.service.BoundDetailService;
import com.miniot.base.service.BoundManageService;
import com.miniot.base.service.DevotionService;
import com.miniot.base.vo.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 出入库管理表
 *
 * @author zzq
 * @date 2023-10-17 11:13:54
 */
@Service
@AllArgsConstructor
@Slf4j
public class BoundManageServiceImpl extends ServiceImpl<BoundManageMapper, BoundManage> implements BoundManageService {

    private final BoundDetailService boundDetailService;
    private final DevotionService devotionService;
    private final BoundManageMapper boundManageMapper;
    private final BoundDetailMapper boundDetailMapper;
    private final WarehouseManageMapper warehouseManageMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveBoundManage(BoundManageVO boundManage) {
        //1 出库 2入库
        Integer boundType = boundManage.getBoundType();
        //入库管理表
        BoundManage boundManage1 = new BoundManage();
        Long id=null;
        int num=0;
        if (ObjectUtil.isNotEmpty(boundManage)){
            BeanUtil.copyProperties(boundManage, boundManage1);
            boundManage1.setOperationTime(new Date());
            //查询自增数值
            BoundManage one = this.getOne(new LambdaQueryWrapper<BoundManage>()
                    .select(BoundManage::getNum)
                    .orderByDesc(BoundManage::getCreateTime)
                    .last("LIMIT 1"));
            if(ObjectUtil.isNotEmpty(one)){
                num=one.getNum();
            }
            //根据自增数值生成订单号
            order(num,boundManage1);
            //插入的数据自增号+1
            boundManage1.setNum(num+1);
            //总的价格先设置为0
            boundManage1.setTotal(new BigDecimal(0));
            this.save(boundManage1);
            id=boundManage1.getId();
        }
        //投入品清单
        if (ObjectUtil.isNotEmpty(boundManage.getDevotionVOS())){
            //投入品
            List<Devotion> devotionList = new ArrayList<>();
            //出入库详情表
            List<BoundDetail> boundDetails = new ArrayList<>();
            List<DevotionVO> devotionVOS = boundManage.getDevotionVOS();
            //拿到添加投入品id
            List<Long> ids = devotionVOS.stream().map(DevotionVO::getDevotionId).collect(Collectors.toList());
            //查出投入品库存数量
            List<Devotion> devotions = devotionService.listByIds(ids);
            Map<Long, Devotion> collect = devotions.stream().collect(Collectors.toMap(Devotion::getId, devotion->devotion));
            for (DevotionVO d:devotionVOS){
                Devotion devotion = collect.get(d.getDevotionId());
                //出库
                if (boundType == 1) {
                    if (devotion.getNumber() < d.getBoundNumber()) {
                        throw new RuntimeException("库存不足");
                    }
                    //出库操作-库存量
                    devotion.setNumber(devotion.getNumber() - d.getBoundNumber());
                    //入库
                } else {
                    devotion.setNumber(devotion.getNumber() + d.getBoundNumber());
                }
                //出入库详情表
                BoundDetail boundDetail = new BoundDetail();
                BeanUtil.copyProperties(d,boundDetail);
                boundDetail.setWarehouseId(boundManage.getWarehouseId());
                Devotion devotion1 = devotionService.getById(d.getDevotionId());
                boundDetail.setTypeId(devotion1.getDevotionParentTypeId());
                boundDetail.setTypeName(devotion1.getDevotionParentTypeName());
                //出入库数量
                BigDecimal decimal2 = new BigDecimal(d.getBoundNumber());
                BigDecimal multiply = d.getBoundPrice().multiply(decimal2);
                //小计
                boundDetail.setSubtotal(multiply);
                boundDetail.setBoundType(boundType);
                boundDetail.setManageId(id);
               // total=multiply.add(decimal2);
                boundDetails.add(boundDetail);
                devotionList.add(devotion);
            }
            boundDetailService.saveBatch(boundDetails);
            devotionService.updateBatchById(devotionList);
        }
        LambdaQueryWrapper<BoundDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BoundDetail::getManageId,boundManage1.getId());
        List<BoundDetail> list = boundDetailService.list(wrapper);
        BigDecimal total = list.stream().map(BoundDetail::getSubtotal).reduce(BigDecimal.ZERO,BigDecimal::add);
        boundManage1.setTotal(total);
        //更新管理表total
        this.updateById(boundManage1);
        return id;
    }

    @Override
    public BoundManageDTO getBoundManageById(Long id) {
        BoundManageDTO boundManageDTO = new BoundManageDTO();
        if (ObjectUtil.isNotEmpty(id)) {
            BoundManage byId = this.getById(id);
            BeanUtil.copyProperties(byId,boundManageDTO);
            List<BoundDetail> list = boundDetailService.list(new LambdaQueryWrapper<BoundDetail>().eq(BoundDetail::getManageId, id));
            List<BoundDetailDTO> collect = list.stream().map(m -> {
                BoundDetailDTO boundDetailDTO = new BoundDetailDTO();
                BeanUtil.copyProperties(m, boundDetailDTO);
                return boundDetailDTO;
            }).collect(Collectors.toList());
            boundManageDTO.setBoundDatilDTOS(collect);
        }
        return boundManageDTO;
    }



    //生成订单号
    private void order(Integer num,BoundManage boundManage1){
        int  lenght= String.valueOf(num).length();
        String order="";
        String o="";
        if(lenght==1){
            o="00"+num;
        }if(lenght==2){
            o="0"+num;
        }if(lenght>=3){
            o=num+"";
        }
        LocalDate now = LocalDate.now();
        if(boundManage1.getBoundType()==1){
             order="ck_"+now.getYear()+now.getMonthValue()+now.getDayOfMonth()+o;
        }else {
            order="rk_"+now.getYear()+now.getMonthValue()+now.getDayOfMonth()+o;
        }
        boundManage1.setOrderNum(order);
    }

    @Override
    public Page<BoundManageDataVO> selectManagementData(Page<BoundManage> page, String time, String warehouseName, String orderNum) {
        LambdaQueryWrapper<BoundManage> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(ObjectUtil.isNotEmpty(warehouseName), BoundManage::getWarehouseName, warehouseName);
        wrapper.eq(ObjectUtil.isNotEmpty(orderNum), BoundManage::getOrderNum, orderNum);
        wrapper.apply(ObjectUtil.isNotEmpty(time), "DATE(create_time) = {0}", time);
        Page<BoundManage> page1 = boundManageMapper.selectPage(page, wrapper);
        List<BoundManage> records = page1.getRecords();
        List<BoundManageDataVO> dataVOS = new ArrayList<>();
        if (!CollectionUtils.isEmpty(records)) {
        for (BoundManage s : records) {
            BoundManageDataVO vo = new BoundManageDataVO();
            BeanUtil.copyProperties(s, vo);
            LambdaQueryWrapper<BoundDetail> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(BoundDetail::getManageId, s.getId());
            List<BoundDetail> list1 = boundDetailService.list(wrapper1);
            List<BoundManageDetailDataVO> list = new ArrayList<>();
            if (!CollectionUtils.isEmpty(list1)) {
                for (BoundDetail s1 : list1) {
                    BoundManageDetailDataVO vo1 = new BoundManageDetailDataVO();
                    BeanUtil.copyProperties(s1, vo1);
                    list.add(vo1);
                }
            }
            vo.setDetail(list);
            //返回数据
            dataVOS.add(vo);
        }
    }
        Page<BoundManageDataVO> result = new Page<>();
        result.setRecords(dataVOS);
        result.setSize(page.getSize());
        result.setCurrent(page.getCurrent());
        result.setTotal(page.getTotal());
        return result;
    }

    @Override
    public Page<InventoryListDataVO> getInventoryListData(Page<WarehouseManage> page, String warehouseName) {
        LambdaQueryWrapper<WarehouseManage> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(ObjectUtil.isNotEmpty(warehouseName), WarehouseManage::getWarehouseName, warehouseName);
        wrapper.orderByDesc(WarehouseManage::getCreateTime);
        Page<WarehouseManage> page1 = warehouseManageMapper.selectPage(page, wrapper);
        List<WarehouseManage> records = page1.getRecords();
        //需要返回的对象
        List<InventoryListDataVO> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(records)) {
            for(WarehouseManage s :records){
                InventoryListDataVO vo = new InventoryListDataVO();
                vo.setWarehouseName(s.getWarehouseName());
                vo.setWarehouseId(s.getId());

                List<Map<Long, Object>> data = boundDetailMapper.selectData(s.getId());
                List<InventoryListDataVO.Type> list1 = new ArrayList<>();
                if (!CollectionUtils.isEmpty(data)) {
                    for (Map<Long, Object> map : data) {
                        String typeName = (String) map.get("typeName");
                        BigDecimal number = (BigDecimal) map.get("number");
                      //  Devotion devotion = devotionService.getById(devotionId);
                        InventoryListDataVO.Type type = new InventoryListDataVO.Type();
                        type.setTypeName(typeName);
                        type.setNumber(number);
                        list1.add(type);
                    }
                    vo.setTypeNumber(list1);
                }
                list.add(vo);
            }
/*            List<Long> ids = records.stream().map(BoundManage::getId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(ids)) {
                List<Map<Long, Object>> list1 = boundDetailMapper.selectData(ids);
                if (!CollectionUtils.isEmpty(list1)) {
                    for (Map<Long, Object> map : list1) {
                        Long devotionId = (Long) map.get("devotionId");
                        BigDecimal number = (BigDecimal) map.get("number");
                        Devotion devotion = devotionService.getById(devotionId);
                        InventoryListDataVO vo = new InventoryListDataVO();
                        vo.setTypeName(devotion.getBrandType());
                        vo.setNumber(number);
                        vo.set
                        list.add(vo);
                    }
                }
            }*/
        }
        Page<InventoryListDataVO> pageData = new Page<>();
        pageData.setCurrent(page1.getCurrent());
        pageData.setPages(page1.getPages());
        pageData.setTotal(page1.getTotal());
        pageData.setRecords(list);
        return pageData;
    }
}
